//== SAGITTARIUS ============================================================================

//== FILEDOC =========================================================================

/** @file backend.h
  * @brief backend
  */

//== BEGINNING OF CODE ===============================================================

#ifndef __SAGUTTARUIS__LLVM_CODEGEN_BACKEND__H_
#define __SAGUTTARUIS__LLVM_CODEGEN_BACKEND__H_

//== INCLUDES ========================================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/backend/llvm/codegen.h"

#ifdef __cplusplus


namespace Sagittarius {
    
    class CodeGen_Network : public CodeGen_Toplevel {
        public:
            typedef CodeGen_Toplevel CodeGen_NetworkSuper;
            
            /// Constructor
            CodeGen_Network(sg_module* m) : CodeGen_Toplevel(m) {}
            
            llvm::Value* emit_exp_node(compiledSrc* c, sg_fctx_val* z, compiledNode* x);
            
            void emit_rxn_rule(compiledSrc* c, sg_fctx_val* z, compiledNode* x, llvm::Value* net);
            
            void emit_rxn_rules(compiledSrc* c, sg_fctx_val* z, compiledNode* x, llvm::Value* net);
            
            /// Node
            llvm::Value* emit_node(compiledSrc* c, sg_fctx_val* z, compiledNode* x);
            
            void createTypes();
            
            void init_internals();
            
            void setup_mappings(llvm::ExecutionEngine* EE);
            
        protected:
            // sg_node_val
            llvm::StructType* node_val;
            llvm::Type* pnode_val;
            
            // sg_reaction_rule_val
            llvm::StructType* rxn_rule_val;
            llvm::Type* prxn_rule_val;
            
            // sg_network_val
            llvm::StructType* network_val;
            llvm::Type* pnetwork_val;
            
            // functions
            
            /// f_create_network
            llvm::Function* f_create_network;
            llvm::FunctionType* f_create_network_tp;
            
            /// f_network_add_rule
            llvm::Function* f_network_add_rule;
            llvm::FunctionType* f_network_add_rule_tp;
            
            /// f_create_reaction
            llvm::Function* f_create_reaction;
            llvm::FunctionType* f_create_reaction_tp;
            
            /// f_create_node
            llvm::Function* f_create_node;
            llvm::FunctionType* f_create_node_tp;
    };
}
#endif

#endif
